import { app,ipcMain}  from 'electron';
import path from 'path';
import db from './datastore';
const pako = require('pako');
const WebSocket  = require('ws');
const moment = require('moment');
const math = require('mathjs');
const HBSpotApi = require('./hb-spot-api');
import axios from 'axios';
import common  from './common';
import { Console, timeStamp } from 'console';

const log = require('electron-log');
let Sleep = function (delay) {
    return new Promise((resolve, reject) => { 
     setTimeout(() => { 
       try {
        resolve(1)
       } catch (e) {
        reject(0)
       }
     }, delay);
    })
   }

function myRound(num,precision){
    if(precision == undefined || precision <= 0){
        return math.floor(num).toString();
    }else{
        let mulNum = '1'
        for(let i= 0;i < parseInt(precision);i++){
            mulNum += '0';
        }
       
        let tempNum = math.chain(math.bignumber(num)).multiply(math.bignumber(mulNum)).done();
        tempNum =   math.floor(tempNum)
        tempNum = math.chain(math.bignumber(tempNum)).divide(math.bignumber(mulNum)).done();
        return tempNum.toString();
    }

}

class Message{
    constructor(id,datetime,message){
        this.id = id;
        this.datetime = datetime;
        this.message = message;
        
    }
}


class Task{

 
    constructor(id){
        this.id = id;
        this.eventMap = new Map();
        this.data = null;
        this.symbol = null;
        this.uping = false;
        this.downing = false;
        this.costPrice = 0;
        this.maxPrice = 0;
        this.minPrice = 0;
        this.prevPrice = undefined;
        this.pending = true;
        this.nextPrices = [];
        
    }
    init(callback){
        
        db.task.findOne({ _id: this.id }).then((doc) => {
            this.data = doc;
            if(this.data.depth == undefined){
                this.data.depth = 30;
            }
            if(this.data.stopTrade == undefined){
                this.data.stopTrade = 0;
            }

            let symbol = global.CONFIG.huobi.symbolMap.get(doc.symbol);
            if(symbol){
                this.symbol = symbol;
                
                this.calCost();

                this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】任务已初始化完成，准备就绪。'))
                callback(true);
            }else{
                this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】任务初始化失败。'))
                callback(false);
            }
           
        });
    }
    refreshData(){
        db.task.findOne({ _id: this.id }).then((doc) => {
            if(doc && this.data){
                this.data.stopTrade = doc.stopTrade == undefined ? 0 : doc.stopTrade;
            }
            
        });
    }
    async startup(){
        this.emitEvent('update',new Message(this.id,this.datetime(),null))
        if(this.ws){
            // if(this.ws.readyState == WebSocket.CONNECTING || this.ws.readyState == WebSocket.OPEN){
            //     this.ws.close();
            // }
            
            this.ws = null;
        }
        
        this.ws = new WebSocket(global.CONFIG.huobi.wsUrl);
        this.ws.on('open',this.onOpen.bind(this));
        this.ws.on('close',this.onClose.bind(this));
        this.ws.on('error',this.onError.bind(this));
        this.ws.on('message',this.onMessage.bind(this));
        if(this.data.buyTradeCount == 0){
            
            
            await this.buyByMarket();
        }else{
            this.pending = false;
        }
        this.startExpense();

    }
    shutdown(){
        if(this.pingInterval){
            clearInterval(this.pingInterval);
        }
        if(this.ws && (this.ws.readyState == WebSocket.OPEN || this.ws.readyState == WebSocket.CONNECTING)){
            this.ws.close();
            this.ws = null;
            this.emitEvent('close',new Message(this.id,this.datetime(),null))
        }
        
        

    }
    async onOpen(){
        this.conned = true;
        this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】任务已建立连接通道。'))
        let sub = `market.${this.data.symbol}.trade.detail`
        this.sendSub(sub);
        this.checkConn();
        //更新任务为启动状态
        await db.task.update({ _id: this.id }, { $set: { state: 1 } });
        this.emitEvent('update',new Message(this.id,this.datetime(),null))

    }
    //检测连接
    checkConn(){
        this.lastPing = Date.now();
        if(this.pingInterval){
            clearInterval(this.pingInterval);
        }
        this.pingInterval = setInterval(()=>{
            if(this.ws && this.ws.readyState == WebSocket.CLOSED){
                clearInterval(this.pingInterval);
                this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】连接异常,自动重连...'))
                this.startup();
            }
            
        },10000)
    }
    async resetConn(){
        this.conned = false;
        while(!this.conned){
            await Sleep(5000)
            if(!this.conned){
                this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】重新连接...'))
                
            }
           
        }

        // while(this.ws && (this.ws.readyState == WebSocket.CLOSING || this.ws.readyState == WebSocket.CLOSED)){
        //     await Sleep(5000)
        //     if(this.ws && (this.ws.readyState == WebSocket.CLOSING || this.ws.readyState == WebSocket.CLOSED)){
        //         this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】重新连接...'))
        //         await this.startup();
        //     }
           
        // }
    }
    onClose(){
        //如果在这里执行close事件,则会在系统异常连接时终止任务
        // this.emitEvent('close',new Message(this.id,this.datetime(),null))
        // if(this.pingInterval){
        //     clearInterval(this.pingInterval);
        // }
        // this.emitEvent('close',new Message(this.id,this.datetime(),null))
        this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】任务已关闭。'))
    }
    state(){
        if(this.ws){
            return this.ws.readyState;
        }else{
            return 0;
        }
       
    }
    onError(err){
        this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】' +  err))
    }
    onMessage(data){
        let text = pako.inflate(data, {to: 'string' });
        let msg = JSON.parse(text);
        if(msg.ping){
            // this.conned = true;
            this.sendPong(msg.ping);
            this.lastPing = msg.ping;
        }else if (msg.tick) {
            if(!this.pending){
                this.onTick(msg.tick);
            }
        } else if(msg.subbed){
            this.conned = true;
            // this.checkConn()
            this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】价格订阅成功。'))
        }else{
            console.log('未知数据...',msg)
        }
    }
    sendPong(pong){
        if(this.ws && this.ws.readyState == WebSocket.OPEN){
            this.ws.send(JSON.stringify({
                pong: pong
            }))
        }
       
    }
    sendSub(sub){
        if(this.ws && this.ws.readyState == WebSocket.OPEN){
            this.ws.send(JSON.stringify({
                "sub": sub,
                "id": this.data._id
              }));
        }

        
    } 
    async onTick(tick){

        this.emitEvent('flicker',new Message(this.id,this.datetime(),null))
        let list = tick.data;
        for(let i in list){
            let price = list[i].price;
            if(this.nextPrices.length > 0){
                if(this.nextPrices[0] != price){
                    this.nextPrices[0] = price;
                }
            }else{
                this.nextPrices[0] = price;
            }
            

        }

    }

    async startExpense(){
        //比较价格
        this.expenseInterval = setInterval(async () => {
            if(this.pending){
                return;
            }
            if(this.ws == null || this.ws.readyState == WebSocket.CLOSED){
                clearInterval(this.expenseInterval)
                return;
             }
            if(this.nextPrices.length > 0){
                let price = this.nextPrices.pop();

                if(this.data.stopTrade == 1){
                    if(this.data.buyTradeCount == 0){
                        this.emitEvent('message',new Message(this.id,this.datetime(),`【只监控不交易】当前价格${price}, 持仓成本价0.00`))
                    }else{
                        if(price > this.costPrice + ''){
                            await this.goup(price)
                        }else{
                            await this.godown(price)
                        }
                    }
                    
                }else{
                    if(this.data.buyTradeCount == 0){
                        this.pending = true;
                        await this.buyByMarket();
                    }else{
                        if(price > this.costPrice + ''){
                            await this.goup(price)
                        }else{
                            await this.godown(price)
                        }
                    }

                }
          
            }

        }, 500);
    }


    async goup(price){
            if(this.pending){
                return;
            }
            //涨价
           
            this.downing = false;
            this.minPrice = 0;
            let diff = math.chain(math.bignumber(price)).subtract(math.bignumber(this.costPrice)).done();
                diff = math.round(diff,this.symbol['price-precision'])
            let upPercent = math.chain(math.bignumber(diff)).divide(math.bignumber(this.costPrice)).multiply(math.bignumber('100')).done();
                upPercent = math.round(upPercent,2)
            this.emitEvent('percent',new Message(this.id,this.datetime(),upPercent+''))
           
            if(this.uping){
                //如果此时价格是一直连续上涨中，则监控价格是否回落或上涨，根据参数设置卖出
                if(price > this.maxPrice){
                    this.emitEvent('message',new Message(this.id,this.datetime(),`【回落监控中】当前价格:${price}, 涨幅${upPercent}%, 本轮最高价格${this.maxPrice}, 当前价格>本轮最高价格, 记录本轮最高价格${price}`))
                    this.maxPrice = price;
                }else{
                    let fallbackPercent = math.chain(math.bignumber(this.data.fallBackPercent)).divide(math.bignumber('100')).done();
                    fallbackPercent = math.round(fallbackPercent,4)
                    let subPriceBig = math.chain(math.bignumber(this.maxPrice)).multiply(math.bignumber(fallbackPercent)).done();
                    subPriceBig = math.round(subPriceBig,this.symbol['price-precision'])

                    let fallbackPricePosition = math.chain(math.bignumber(this.maxPrice)).subtract(math.bignumber(subPriceBig)).done();
                    fallbackPricePosition = math.round(fallbackPricePosition,this.symbol['price-precision'])

                    // try{
                    //     this.emitEvent('message',new Message(this.id,this.datetime(),`【系统日志】price:${price},type:${typeof(price)},subPriceBig:${subPriceBig},type:${typeof(subPriceBig)},costPrice:${this.costPrice},fallbackPercent:${fallbackPercent},maxPrice:${this.maxPrice}`))
                    // }catch(err){
                    //     this.emitEvent('message',new Message(this.id,this.datetime(),`${err}`))
                    // }
                    // this.printCustom(`最新单价：${price} \t  止盈单价：${fallbackPricePosition}`)
                    this.emitEvent('message',new Message(this.id,this.datetime(),`【回落监控中】当前价格${price}, 涨幅${upPercent}%, 本轮最高价格${this.maxPrice}, 回落百分比${this.data.fallBackPercent}%，止盈单价${fallbackPricePosition}`))
                    if(price <= fallbackPricePosition){
                        // 如果此时价格<=回落百分比位置，则下单卖出
                        this.pending = true;
                        this.emitEvent('message',new Message(this.id,this.datetime(),`【回落监控中】价格回落, 达到回落百分比${this.data.fallBackPercent}%，达到止盈单价${fallbackPricePosition}, 执行卖出操作...`))
                        //卖出
                        await this.sellByMarket();
                        //检查是否停止任务
                        let docData = await db.task.findOne({ _id: this.id });
                        if(docData && docData.quit == 1){
                            this.shutdown();
                            this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】完成本轮交易，系统自动停止任务。'))

                        }else{
                            
                            await this.buyByMarket();
                        }
                       
                    }

                }
            }else{
               
                if(upPercent >= Number(this.data.profitPercent)){
                    //达到卖出要求
                    if(this.data.fallBackPercent == undefined || Number(this.data.fallBackPercent) == 0){
                        //如果未设置回落百分比则卖出
                        this.pending = true;
                        this.emitEvent('message',new Message(this.id,this.datetime(),`【止盈监控中】未设置回落, 当前价格${price}, 涨幅${upPercent}%, 达到止盈百分比${this.data.profitPercent}%， 执行卖出操作...`))
                        //卖出
                        await this.sellByMarket();
                        //检查是否停止任务
                        let docData = await db.task.findOne({ _id: this.id });
                        if(docData && docData.quit == 1){
                            this.shutdown();
                            this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】完成本轮交易，系统自动停止任务。'))

                        }else{
                            await this.buyByMarket();
                        }
                        
                        
                    }else{
                        this.uping = true;
                        this.maxPrice = price;
                        this.emitEvent('message',new Message(this.id,this.datetime(),`【止盈监控中】设置了回落百分比, 当前价格${price}, 涨幅${upPercent}%, 止盈百分比${this.data.profitPercent}%, 记录最高价格${this.maxPrice}`))
                    }

                }else{
                    this.emitEvent('message',new Message(this.id,this.datetime(),`【止盈监控中】当前价格${price}, 涨幅${upPercent}%, 止盈百分比${this.data.profitPercent}%`))
                }


            }
    }
    async godown(price){
            if(this.pending){
                return;
            }
            this.uping = false;
            this.maxPrice = 0;
            // 如果当前买进下单次数大于设置的下单次数，则停止执行
            let diff = math.chain(math.bignumber(this.costPrice)).subtract(math.bignumber(price)).done();
                diff = math.round(diff,this.symbol['price-precision'])
            let downDecimal = math.chain(math.bignumber(diff)).divide(math.bignumber(this.costPrice)).done();
            let downPercent = math.chain(math.bignumber(downDecimal)).multiply(math.bignumber('100')).done();
                downPercent = math.round(downPercent,2)

            this.emitEvent('percent',new Message(this.id,this.datetime(),`-${downPercent}`))
            if(this.data.buyTradeCount >= this.data.buyMoneys.length){
                this.emitEvent('message',new Message(this.id,this.datetime(),`【补单监控中】买进次数达到上限, 当前价格${price}, 涨幅-${downPercent}%`))
                return;
            }

            //计算下一单买进价格
            let subPrice = math.chain(math.bignumber(this.data.buyBasePrice)).multiply(math.bignumber(this.data.depth / 100)).done()
                subPrice = math.round(subPrice,this.symbol['price-precision'])
            let subPriceUnit = math.chain(math.bignumber(subPrice)).divide(math.bignumber(this.data.buyMoneys.length-1))
                                                                    .multiply(math.bignumber(this.data.buyTradeCount))
                                                                    .done();
                subPriceUnit = math.round(subPriceUnit,this.symbol['price-precision'])
            //下一单买进价格
            let positionPrice = math.chain(math.bignumber(this.data.buyBasePrice)).subtract(math.bignumber(subPriceUnit)).done()
                positionPrice = math.round(positionPrice,this.symbol['price-precision'])
               
            
            if(this.downing){
                 //如果此次价格，比上次的价格更低，将此次价格置为最低价格
                if(price < this.minPrice){
                    this.emitEvent('message',new Message(this.id,this.datetime(),`【反弹监控中】当前价格:${price}, 涨幅-${downPercent}%, 本轮最低价格${this.minPrice}, 当前价格<本轮最低价格, 记录本轮最低价格${price}`))
                    this.minPrice = price;
                }else{
                    //如果此次价格高于上次价，则比较是否达到反弹百分比位置，如果达到则下单摊平
                    

                    let reboundPercent = math.chain(math.bignumber(this.data.reboundPercent)).divide(math.bignumber('100')).done();
                    reboundPercent = math.round(reboundPercent,4)
/**
                    //10%:动态计算反弹百分比的基数，超过此基数，每超过5个百分比，则反弹百分比就增加一个百分比
                    if(downDecimal > 0.1){
                        
                        //如果跌幅超过动态计算反弹百分比的基数10%的时候，则计算超过了几个5个百分比
                        let unitDecimal = math.chain(math.bignumber(downDecimal)).divide(math.bignumber('0.05')).done();
                            //取整数
                            unitDecimal =  myRound(unitDecimal,0);
                            ////增加基数：每增加5个百分比，反弹百分比就增加1个百分比
                            let addPercent = math.chain(math.bignumber(unitDecimal)).multiply(math.bignumber('0.01')).done();
                            reboundPercent =  math.chain(math.bignumber(reboundPercent)).add(math.bignumber(addPercent)).done();
                            reboundPercent = math.round(reboundPercent,4)

                            this.emitEvent('message',new Message(this.id,this.datetime(),`【系统消息】跌幅超过10%，启动动态反弹百分比：${reboundPercent * 100}%`))
                    }
*/
                    let reboundSubPrice = math.chain(math.bignumber(this.data.buyBasePrice)).multiply(math.bignumber(reboundPercent)).done();
                    reboundSubPrice = math.round(reboundSubPrice,this.symbol['price-precision'])

                    let reboundPricePosition = math.chain(math.bignumber(this.minPrice)).add(math.bignumber(reboundSubPrice)).done();
                        reboundPricePosition = math.round(reboundPricePosition,this.symbol['price-precision'])

                    this.emitEvent('message',new Message(this.id,this.datetime(),`【反弹监控中】当前价格${price}, 涨幅-${downPercent}%, 本轮最低价格${this.minPrice}, 反弹百分比${this.data.reboundPercent}%, 补单价格${reboundPricePosition}`))

                    if(price >= reboundPricePosition){
                        this.pending = true;
                        this.emitEvent('message',new Message(this.id,this.datetime(),`【反弹监控中】价格反弹，达到反弹百分比${this.data.reboundPercent}%，达到补单价格${reboundPricePosition}, 执行第${this.data.buyTradeCount + 1}单买进操作...`))
                        await this.buyByMarket();
                    }


                }



            }else{
                // this.printCustom(`最新单价：${price} \t 下一单补仓单价：${positionPrice}`)
                if(price <= positionPrice){

                    if(this.data.reboundPercent == undefined || Number(this.data.reboundPercent) == 0){
                        //如果未设置反弹百分比则买入
                        this.pending = true;
                        this.emitEvent('message',new Message(this.id,this.datetime(),`【补单监控中】未设置反弹百分比, 当前价格${price}, 涨幅-${downPercent}%, 达到第${this.data.buyTradeCount + 1}单补单价格${positionPrice}，执行买进操作...`))
                        //买进
                        await this.buyByMarket();
                    }else{
                        this.downing = true;
                        this.minPrice = price;
                        this.emitEvent('message',new Message(this.id,this.datetime(),`【补单监控中】设置了反弹百分比, 当前价格${price}, 涨幅-${downPercent}%, 记录最低价格${this.minPrice}`))
                    }


                }else{
                    this.emitEvent('message',new Message(this.id,this.datetime(),`【补单监控中】当前价格${price}, 涨幅-${downPercent}%, 补单价格${positionPrice}`))
                }
            }

    }
    async sellByMarket(){
        if(this.data.stopTrade == 1){
            this.pending = false;
            return;
        }
        let success = false;
         let sellAmount = "0";
        if(this.data.accountBalance){
             //获取余额
             for(let n = 1; n <= 10; n++){
                this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】待卖出仓位余额查询...'))
                let balanceResult = await HBSpotApi.getOneBalance({'currency':this.symbol['base-currency']});
                if(balanceResult.success){
                    sellAmount = myRound(balanceResult.data,this.symbol['amount-precision']);
                    success = true;
                    break;
                }else{
                    this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】待卖出仓位余额查询失败...'))
                }
            }
        }

        if(!success){
            if(this.data.accountBalance){
                this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】计算待卖出数量...'))
            }
            sellAmount = myRound(this.data.totalAmount,this.symbol['amount-precision'])
        }
        

        let orderId = null;
        for(let n = 1; n <= 10; n++){
            let sellResult = await HBSpotApi.sellByMarket({symbol:this.data.symbol,amount:sellAmount})
            if(sellResult.success){
                this.emitEvent('message',new Message(this.id,this.datetime(),'【卖出下单】下单成功'))
                orderId = sellResult.data;
                break;
            }else{
                if(n < 10){
                    this.emitEvent('message',new Message(this.id,this.datetime(),'【卖出下单】下单失败：' + sellResult.data))
                    this.emitEvent('message',new Message(this.id,this.datetime(),'【卖出下单】重试下单...'))
                }else{
                    this.emitEvent('message',new Message(this.id,this.datetime(),'【卖出下单】多次下单失败，终止任务。'))
                    this.shutdown();
                }
            }
        }
        if(orderId == null){
            return;
        }
         // 查询订单状态
         this.emitEvent('message',new Message(this.id,this.datetime(),'【订单状态】查询订单状态...'))
         for(let n = 1; n <= 10; n++){
            await Sleep(2000);
            let orderResult = await HBSpotApi.getOrder({orderId:orderId})

            if(orderResult.success){
                if(orderResult.data.state == 'filled'){
                    this.emitEvent('message',new Message(this.id,this.datetime(),'【订单状态】订单交易完成。'))
                    let fieldCashAmount = orderResult.data['field-cash-amount'];
                    let fieldFees = orderResult.data['field-fees'];
                    //保存订单祥情
                    let currentMoney = math.chain(math.bignumber(fieldCashAmount)).subtract(math.bignumber(fieldFees)).done();
                    currentMoney = math.round(currentMoney,this.symbol['value-precision']).toString()
                    let trade = {
                        taskId:this.id,
                        symbol:this.data.symbol,
                        loopCount:this.data.loopCount,
                        status:0,
                        orderId:orderId,
                        type:'sell-market',
                        tradeMode:1,
                        direction:'sell',
                        money:currentMoney,
                        amount:sellAmount,
                        baseCurrency:this.symbol['base-currency'],
                        quoteCurrency:this.symbol['quote-currency']
                    }
                    await db.trade.insert(trade);
                    
                    //并且更新本轮订单状态为已完成
                    await db.trade.update({ taskId: this.id,loopCount:this.data.loopCount },{ $set:{
                        status:1,
                    }},{ multi: true });

                    //查询本轮交易明细，生成交易报告
                    try {
                        common.insertReport(this.id,this.data.loopCount);
                     } catch (error) {
                         
                     }

                    this.data.buyTradeCount = 0;
                    this.data.totalMoney = '0';
                    this.data.totalAmount = '0'
                    this.data.loopCount++;

                     //更新任务状态
                     await db.task.update({ _id: this.id }, {$set: {
                        buyTradeCount:this.data.buyTradeCount,
                        totalMoney:this.data.totalMoney,
                        totalAmount:this.data.totalAmount,
                        loopCount:this.data.loopCount
                     }});

                  
                  
                    this.emitEvent('update',new Message(this.id,this.datetime(),null))
                    this.uping = false;
                    this.downing = false;
                    this.maxPrice = 0;
                    this.costPrice = 0;
                    this.prevPrice = undefined;




                    
                    break;
                }else{
                    this.emitEvent('message',new Message(this.id,this.datetime(),'【订单状态】等待订单完成...'))
                    n--;
                }
                
            }else{
                // 失败
                if(n < 10){
                    this.emitEvent('message',new Message(this.id,this.datetime(),'【订单状态】订单状态获取失败：' + orderResult.data))
                    this.emitEvent('message',new Message(this.id,this.datetime(),'【订单状态】重试查询订单状态...'))
                }else{
                    this.emitEvent('message',new Message(this.id,this.datetime(),'【订单状态】多次订单祥情获取失败，终止任务。'))
                    this.shutdown();
                }
            }
         }
    }
    async buyByMarket(){
        if(this.data.stopTrade == 1){
            this.pending = false;
            return;
        }
        let isFirst = false;
        if(this.data.buyTradeCount == 0){
             //购买本轮第一单
             this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】初始化新一轮交易...'))
             this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】市价买进本轮第1单...'))
            isFirst = true;
        }
        let money = this.data.buyMoneys[this.data.buyTradeCount].value;
        money = math.round(money,this.symbol['value-precision']).toString();
       
        let orderId = null;
        for(let n = 1; n <= 10; n++){
            let buyResult = await HBSpotApi.buyByMarket({symbol:this.data.symbol,amount:money})
            if(buyResult.success){
                this.emitEvent('message',new Message(this.id,this.datetime(),'【买进下单】下单成功'))
                orderId = buyResult.data;
                break;
            }else{
                if(n < 10){
                    this.emitEvent('message',new Message(this.id,this.datetime(),'【买进下单】下单失败：' + buyResult.data))
                    this.emitEvent('message',new Message(this.id,this.datetime(),'【买进下单】重试下单...'))
                }else{
                    this.emitEvent('message',new Message(this.id,this.datetime(),'【买进下单】多次下单失败，终止任务。'))
                    this.shutdown();
                }
               
            }
        }
        if(orderId == null){
            return;
        }
            // 查询订单状态
            this.emitEvent('message',new Message(this.id,this.datetime(),'【订单状态】查询订单状态...'))
            for(let n = 1; n <= 10; n++){
                await Sleep(2000);
                let orderResult = await HBSpotApi.getOrder({orderId:orderId})
                if(orderResult.success){
                   
                    if(orderResult.data.state == 'filled'){
                        this.emitEvent('message',new Message(this.id,this.datetime(),'【订单状态】订单交易完成。'))
                        let fieldAmount = orderResult.data['field-amount'];
                        let fieldFees = orderResult.data['field-fees'];
                        //保存订单祥情
                        let currentAmount = math.chain(math.bignumber(fieldAmount)).subtract(math.bignumber(fieldFees)).done();
                        currentAmount = math.round(currentAmount,this.symbol['value-precision']).toString()
                        let trade = {
                            taskId:this.id,
                            symbol:this.data.symbol,
                            loopCount:this.data.loopCount,
                            status:0,
                            orderId:orderId,
                            type:'buy-market',
                            tradeMode:1,
                            direction:'buy',
                            money:money,
                            amount:currentAmount,
                            baseCurrency:this.symbol['base-currency'],
                            quoteCurrency:this.symbol['quote-currency']
                        }
                        await db.trade.insert(trade);
                       
                        this.data.buyTradeCount ++;

                        let tempTotalMoney = math.chain(math.bignumber(this.data.totalMoney)).add(math.bignumber(money)).done();
                        this.data.totalMoney = math.round(tempTotalMoney,this.symbol['value-precision']).toString()
                        //如果任务设置了使用账户余额初始化，则优先使用交易后的账户余额
                        let success = false;
                        if(this.data.accountBalance){
                            //获取余额
                            for(let n = 1; n <= 10; n++){
                                this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】已成交数量查询...'))
                                let balanceResult = await HBSpotApi.getOneBalance({'currency':this.symbol['base-currency']});
                                if(balanceResult.success){
                                    this.data.totalAmount = myRound(balanceResult.data,this.symbol['amount-precision']);
                                    success = true;
                                    break;
                                }else{
                                    this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】已成交数量查询失败...'))
                                }
                            }
                        }

                        if(!success){
                            if(this.data.accountBalance){
                                this.emitEvent('message',new Message(this.id,this.datetime(),'【系统消息】计算已成交数量...'))
                            }
                            let tempTotalAmount = math.chain(math.bignumber(this.data.totalAmount)).add(math.bignumber(currentAmount)).done();
                            this.data.totalAmount =  myRound(tempTotalAmount,this.symbol['amount-precision'])
                        }
                        

                        this.calCost();

                        let updateData = {
                            buyTradeCount:this.data.buyTradeCount,
                            totalMoney:this.data.totalMoney,
                            totalAmount:this.data.totalAmount
                         }
                         if(isFirst){
                             this.data.buyBasePrice = this.costPrice;
                            updateData['buyBasePrice'] =  this.costPrice + '';
                         }
                         //更新任务状态
                         await db.task.update({ _id: this.id }, {$set: updateData});
                         this.emitEvent('update',new Message(this.id,this.datetime(),null))
                        this.uping = false;
                        this.downing = false;
                        this.pending = false;
                        break;
                    }else{
                        this.emitEvent('message',new Message(this.id,this.datetime(),'【订单状态】等待订单完成...'))
                        n--;
                    }
                    
                }else{
                    // 失败
                    if(n < 10){
                        this.emitEvent('message',new Message(this.id,this.datetime(),'【订单状态】订单状态获取失败：' + orderResult.data))
                        this.emitEvent('message',new Message(this.id,this.datetime(),'【订单状态】重试查询订单状态...'))
                    }else{
                        this.emitEvent('message',new Message(this.id,this.datetime(),'【订单状态】多次订单祥情获取失败，终止任务。'))
                        this.shutdown();
                    }
                }
            }


  
        
    }
    calCost(){
        //计算当前成本单价
        if(this.data.totalMoney != undefined && Number(this.data.totalMoney) != 0
         && this.data.totalAmount != undefined && Number(this.data.totalAmount) != 0){
            let tempPrice = math.chain(math.bignumber(this.data.totalMoney)).divide(math.bignumber(this.data.totalAmount)).done();
            this.costPrice = math.round(tempPrice,this.symbol['price-precision'])
         }
    }
    on(event,fun){
        let funs = this.eventMap.get(event)
        if(funs){
            funs.push(fun);
        }else{
            this.eventMap.set(event,[fun])
        }
    }
    datetime(){
        return moment().format('YYYY-MM-DD HH:mm:ss');
    }
    emitEvent(name,message){
        if(name == 'message'){
            this.printData();
            this.printMessage(message.message);
        }
        let funs = this.eventMap.get(name);
        if(funs){
            for(var i in funs){
                funs[i](message)
            }
        }
    }
    printData(){
        let msg = `[DATA] \t id:${this.id}  \t symbol:${this.data.symbol} \t 轮数:${this.data.loopCount}  \t 补单金额:${JSON.stringify(this.data.buyMoneys)} \t 本轮购买单数:${this.data.buyTradeCount}  \t 首单购买单价:${this.data.buyBasePrice}  \t 深度:${this.data.buyLevel}  \t 反弹百分比:${this.data.reboundPercent} \t 止盈百分比:${this.data.profitPercent} \t 回落百分比:${this.data.fallBackPercent} \t 涨:${this.uping}  \t 跌:${this.downing}  \t 深度百分比:${this.data.depth}  \t 成本单价:${this.costPrice}  \t 本轮最高价格:${this.maxPrice}  \t 本轮最低价格:${this.minPrice}  \t 上一次单价:${this.prevPrice} \t 等待:${this.pending};`;
        log.info(msg);
    }
    printMessage(message){
        let msg = `[MESSAGE]  \t ${this.id}  \t ${this.data.symbol}  \t ${message}`;
        log.info(msg);
    }

    printCustom(message){
        let msg = `[CUSTOM]  \t ${this.id}  \t ${this.data.symbol}  \t ${message}`;
        log.info(msg);
    }

}




export default Task